
import ssl
import threading
import websocket
import time
from manager import pushNotifications
from flask import json

from manager.models import GateKline, GateKlineSchema
from manager import gateDao

klines_schema = GateKlineSchema(many=True)
kline_schema = GateKlineSchema()



class GateWS(object):

    all_ws = []

    def __init__(self,
                 pair_name='',
                 id=int(time.time()) - 1533820000,
                 timestamp=int(time.time()) - 432000, #int(time.time()) - 864000,  # timestamp=int(time.time()) - 2592000,
                 group_sec=60,
                 autosync=True):
        last_kline = gateDao.query_last_kline(pair_name)

        start_timestamp = timestamp
        if last_kline:
            start_timestamp = (last_kline.timestamp + group_sec) if (last_kline.timestamp + group_sec) > timestamp else timestamp
        self.id = id
        self.pair_name = pair_name
        self.timestamp = start_timestamp
        self.method = 'kline.query'
        self.group_sec = group_sec
        self.autosync = autosync

    def on_message(self, ws, message):
        print('\n \n')
        print('GateWS - on_message ----------------*** ' + self.pair_name + ' ***--------------------------------')
        print(str(threading.current_thread()))
        print('----------------------------------------------------------------------------')
        print('已 激 活 的 线 程数为：     %d' % threading.active_count())
        print('查看现在正在运行的线程：     %s' % threading.current_thread())
        print('当 前 运 行 线 程数为：     %s' % threading.enumerate())
        print('\n \n')
        result_json = json.loads(message)

        if 'method' in result_json and 'params' in result_json:

            last_kline = gateDao.update_klines(result_json['params'], self.pair_name, self.group_sec)
            if last_kline is not None:
                print('----- 自动同步 --- "%s" ----- %d' % (last_kline.pair_name, last_kline.timestamp))
            else:
                print('----- 自动同步 --- "%s" ----- 存储失败' % self.pair_name)

        elif 'result' in result_json and result_json['result'] is not None:

            if isinstance(result_json['result'], dict):
                print('----- 自动同步 ------- "%s" ----- 启动成功' % self.pair_name)
            elif isinstance(result_json['result'], list):
                last_kline = gateDao.insert_klines(result_json['result'], self.pair_name)
                if last_kline is not None:
                    self.timestamp = last_kline.timestamp + self.group_sec
                    request_aip = '{"id":%d, "method":"%s", "params":["%s", %d, %d, %d]}' % (
                        self.id, self.method, self.pair_name, self.timestamp, self.timestamp + 43200, self.group_sec)
                    ws.send(request_aip)
                    print(' ------- 刷新数据 --- "%s" ---' % self.pair_name)
                elif self.autosync:
                    self.method = 'kline.subscribe'
                    request_aip = '{"id":%d, "method":"%s", "params":["%s", %d]}' % (
                        self.id, self.method, self.pair_name, self.group_sec)
                    ws.send(request_aip)
                    print(' ------- 自动同步 --- "%s" --- 正在启动 ' % self.pair_name)

                    pair = gateDao.query_one_pair(self.pair_name)
                    if pair is not None:
                        pair.autosync = 1
                        gateDao.object_merge(pair)
                else:
                    print(' 关闭 1 +++++++ %s ++++++ %s ' % (message, self.method))
                    ws.close()
            else:
                print(' 关闭 2 +++++++ %s ++++++ %s ' % (message, self.method))
                ws.close()
        elif self.method == 'kline.query' and self.autosync:
            self.method = 'kline.subscribe'
            request_aip = '{"id":%d, "method":"%s", "params":["%s", %d]}' % (
                self.id, self.method, self.pair_name, self.group_sec)
            ws.send(request_aip)
            print(' ------- 自动同步 --- "%s" --- 正在启动 ' % self.pair_name)

            pair = gateDao.query_one_pair(self.pair_name)
            if pair is not None:
                pair.autosync = 1
                gateDao.object_merge(pair)
        else:
            print(' 关闭 3 +++++++ %s ++++++ %s ' % (message, self.method))
            ws.close()

    def on_error(self, ws, error):
        print(error)

    def on_close(self, ws):
        print("### +++++++++++++ closed +++++++++++++ ###")

        pair = gateDao.query_one_pair(self.pair_name)
        if pair is not None:
            pair.autosync = 0
            gateDao.object_merge(pair)

        alert = '🔴🔴🔴 Gate --- %s --- 关闭监控' % self.pair_name
        pushNotifications.all(alert=alert)

    def on_open(self, ws):
        message = '{"id":%d, "method":"%s", "params":["%s", %d, %d, %d]}' % (
            self.id, self.method, self.pair_name, self.timestamp, self.timestamp + 43200, self.group_sec)
        ws.send(message)
        alert = '✅✅✅ Gate --- %s --- 开启监控' % self.pair_name
        pushNotifications.all(alert=alert)

        GateWS.all_ws.append(self)

    def on_ping(self, ws):
        send_msg = '{"id":%d, "method":"server.ping", "params":[]}' % self.id
        ws.send(send_msg)

    def on_pong(self, ws, args):
        print('*******  pong ------------ %s ------------ %s ------------ %s' % (self.id, self.pair_name, args))


    def start_ws(self):

        # websocket.enableTrace(True)

        ws = websocket.WebSocketApp("wss://ws.gate.io/v3/",
                                    on_message=self.on_message,
                                    on_error=self.on_error,
                                    on_close=self.on_close,
                                    on_ping=self.on_ping,
                                    on_pong=self.on_pong)
        ws.on_open = self.on_open


        ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE},
                       http_proxy_host="127.0.0.1",
                       http_proxy_port=1087,
                       ping_interval=30,
                       ping_timeout=20
                       )